// Auth subnets are for authentication servers
resource "aws_route_table" "auth" {
  count  = "${length(local.azs)}"
  vpc_id = "${local.vpc_id}"

  tags {
    TeleportCluster = "${var.cluster_name}"
  }
}

// Route all outbound traffic through NAT gateway
// Auth servers do not have public IP address and are located
// in their own subnet restricted by security group rules.
resource "aws_route" "auth" {
  count                  = "${length(local.azs)}"
  route_table_id         = "${element(aws_route_table.auth.*.id, count.index)}"
  destination_cidr_block = "0.0.0.0/0"
  nat_gateway_id         = "${element(local.nat_gateways, count.index)}"
  depends_on             = ["aws_route_table.auth"]
}

// This is a private subnet for auth servers.
resource "aws_subnet" "auth" {
  count             = "${length(local.azs)}"
  vpc_id            = "${local.vpc_id}"
  cidr_block        = "${cidrsubnet(var.vpc_cidr, 8, count.index)}"
  availability_zone = "${element(local.azs, count.index)}"
  tags {
    TeleportCluster = "${var.cluster_name}"
  }
}

resource "aws_route_table_association" "auth" {
  count          = "${length(local.azs)}"
  subnet_id      = "${element(aws_subnet.auth.*.id, count.index)}"
  route_table_id = "${element(aws_route_table.auth.*.id, count.index)}"
}

// Security groups for auth servers only allow access to 3025 port from
// public subnets, and not the internet
resource "aws_security_group" "auth" {
  name   = "${var.cluster_name}-auth"
  vpc_id = "${local.vpc_id}"
  tags {
    TeleportCluster = "${var.cluster_name}"
  }
}

// SSH emergency access via bastion security groups
resource "aws_security_group_rule" "auth_ingress_allow_ssh" {
  type              = "ingress"
  from_port         = 22
  to_port           = 22
  protocol          = "tcp"
  security_group_id = "${aws_security_group.auth.id}"
  source_security_group_id = "${aws_security_group.bastion.id}"
}

// Internal traffic within the security group is allowed.
resource "aws_security_group_rule" "auth_ingress_allow_internal_traffic" {
  type              = "ingress"
  from_port         = 0
  to_port           = 0
  protocol          = "-1"
  self              = true
  security_group_id = "${aws_security_group.auth.id}"
}

// Allow traffic from public subnet to auth servers - this is to
// let proxies to talk to auth server API.
// This rule uses CIDR as opposed to security group ip becasue traffic coming from NLB
// (network load balancer from Amazon)
// is not marked with security group ID and rules using the security group ids do not work,
// so CIDR ranges are necessary.
resource "aws_security_group_rule" "auth_ingress_allow_cidr_traffic" {
  type              = "ingress"
  from_port         = 3025
  to_port           = 3025
  protocol          = "tcp"
  cidr_blocks       = ["${aws_subnet.public.*.cidr_block}"]
  security_group_id = "${aws_security_group.auth.id}"
}

// Allow traffic from nodes to auth servers.
// Teleport nodes heartbeat presence to auth server.
// This rule uses CIDR as opposed to security group ip becasue traffic coming from NLB
// (network load balancer from Amazon)
// is not marked with security group ID and rules using the security group ids do not work,
// so CIDR ranges are necessary.
resource "aws_security_group_rule" "auth_ingress_allow_node_cidr_traffic" {
  type              = "ingress"
  from_port         = 3025
  to_port           = 3025
  protocol          = "tcp"
  cidr_blocks       = ["${aws_subnet.node.*.cidr_block}"]
  security_group_id = "${aws_security_group.auth.id}"
}

// This rule allows non NLB traffic originating directly from proxies
resource "aws_security_group_rule" "auth_ingress_allow_public_traffic" {
  type              = "ingress"
  from_port         = 3025
  to_port           = 3025
  protocol          = "tcp"
  source_security_group_id = "${aws_security_group.proxy.id}"
  security_group_id = "${aws_security_group.auth.id}"
}

// All egress traffic is allowed
resource "aws_security_group_rule" "auth_egress_allow_all_traffic" {
  type              = "egress"
  from_port         = 0
  to_port           = 0
  protocol          = "-1"
  cidr_blocks       = ["0.0.0.0/0"]
  security_group_id = "${aws_security_group.auth.id}"
}


// Network load balancer for auth server.
resource "aws_lb" "auth" {
  name            = "${var.cluster_name}-auth"
  internal        = true
  subnets         = ["${aws_subnet.public.*.id}"]
  load_balancer_type = "network"
  idle_timeout    = 3600

  tags {
    TeleportCluster = "${var.cluster_name}"
  }
}

// Target group is associated with auto scale group
resource "aws_lb_target_group" "auth" {
  name     = "${var.cluster_name}-auth"
  port     = 3025
  vpc_id   = "${aws_vpc.teleport.id}"
  protocol = "TCP"
}

// 3025 is the Auth servers API server listener.
resource "aws_lb_listener" "auth" {
  load_balancer_arn = "${aws_lb.auth.arn}"
  port              = "3025"
  protocol = "TCP"

  default_action {
    target_group_arn = "${aws_lb_target_group.auth.arn}"
    type             = "forward"
  }
}
